package com.tsfyun.scm.service.impl.report;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.DateUtils;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TypeUtils;
import com.tsfyun.scm.service.logistics.ICrossBorderWaybillService;
import com.tsfyun.scm.service.order.IExpOrderService;
import com.tsfyun.scm.service.order.IImpOrderService;
import com.tsfyun.scm.service.report.IExpReportService;
import com.tsfyun.scm.service.report.IImpReportService;
import com.tsfyun.scm.service.report.IWelcomeService;
import com.tsfyun.scm.vo.report.ImpExpAgencyFeeVO;
import com.tsfyun.scm.vo.report.ImpExpTotalDataVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.function.Function;
import java.util.stream.IntStream;

@Slf4j
@Service
public class WelcomeServiceImpl implements IWelcomeService {

    @Autowired
    private IImpOrderService iImpOrderService;
    @Autowired
    private IExpOrderService iExpOrderService;
    @Autowired
    private ICrossBorderWaybillService crossBorderWaybillService;
    @Autowired
    private IImpReportService impReportService;
    @Autowired
    private IExpReportService expReportService;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public ImpExpTotalDataVO impExpTotalData() {
        ImpExpTotalDataVO result = new ImpExpTotalDataVO();
        Date dayStartDate = DateUtils.getDayStart(new Date());
        Date dayEndDate = DateUtils.getDayEnd(new Date());
        Date monthStartDate = DateUtils.getMonthFirst(dayStartDate);
        Date monthEndDate = DateUtils.getMonthEnd(dayStartDate);

        //此处优化成三个线程来查询
        CountDownLatch countDownLatch = new CountDownLatch(3);
        IntStream.range(0, 3).forEach(idx -> threadPoolTaskExecutor.execute(() -> {
            try {
                if (0 == idx) {
                    // 当日进口单量
                    result.setDayImpSingleQuantity(iImpOrderService.totalSingleQuantity(dayStartDate, dayEndDate));
                    // 当日出口单量
                    result.setDayExpSingleQuantity(iExpOrderService.totalSingleQuantity(dayStartDate, dayEndDate));
                    // 本月进口单量
                    result.setMonthImpSingleQuantity(iImpOrderService.totalSingleQuantity(monthStartDate, monthEndDate));
                    // 本月出口单量
                    result.setMonthExpSingleQuantity(iExpOrderService.totalSingleQuantity(monthStartDate, monthEndDate));
                } else if (1 == idx) {
                    // 当日进口金额
                    result.setDayImpAmountMoney(iImpOrderService.totalAmountMoney(dayStartDate, dayEndDate));
                    // 当日出口金额
                    result.setDayExpAmountMoney(iExpOrderService.totalAmountMoney(dayStartDate, dayEndDate));
                    // 本月进口金额
                    result.setMonthImpAmountMoney(iImpOrderService.totalAmountMoney(monthStartDate, monthEndDate));
                    // 本月出口金额
                    result.setMonthExpAmountMoney(iExpOrderService.totalAmountMoney(monthStartDate, monthEndDate));
                } else if (2 == idx) {

                    // 当日进口车次
                    result.setDayImpTrainNumber(crossBorderWaybillService.impTrainNumber(dayStartDate, dayEndDate));
                    // 当日出口车次
                    result.setDayExpTrainNumber(crossBorderWaybillService.expTrainNumber(dayStartDate, dayEndDate));
                    // 本月进口车次
                    result.setMonthImpTrainNumber(crossBorderWaybillService.impTrainNumber(monthStartDate, monthEndDate));
                    // 本月出口车次
                    result.setMonthExpTrainNumber(crossBorderWaybillService.expTrainNumber(monthStartDate, monthEndDate));
                }
            } catch (Exception e) {
                log.error("处理车次数据异常",e);
            } finally {
                countDownLatch.countDown();
            }
        }));
        try {
            countDownLatch.await();
        } catch (Exception e){}
        return result;
    }

    @Override
    public Map<String, ImpExpTotalDataVO> monthSummaryImpExpTotalData(String year) {
        if(StringUtils.isNotEmpty(year) && (!StringUtils.isInteger(year) || year.length() != 4)) {
            throw new ServiceException("年份不正确");
        }
        Map<String, ImpExpTotalDataVO> resultMap = Maps.newHashMap();
        String currentMonth = DateUtils.getCurrentDateMonth();
        String currentYear = DateUtils.getCurrentDateYear();
        year = TypeUtils.castToString(year,DateUtils.getCurrentDateYear());
        //按当前年份查询
        boolean flag = Objects.equals(currentYear,year);

        final Integer[] monthGroup1 = {1,2,3,4};
        final Integer[] monthGroup2 = {5,6,7,8};
        final Integer[] monthGroup3 = {9,10,11,12};
        Map<Integer,Integer[]> threadMonthMap = Maps.newHashMap();
        threadMonthMap.put(0,monthGroup1);
        threadMonthMap.put(1,monthGroup2);
        threadMonthMap.put(2,monthGroup3);
        String finalYear = year;
        Function<Integer[],Map<String, ImpExpTotalDataVO>> queryF = (x)->{
            Map<String, ImpExpTotalDataVO> handleMap = Maps.newHashMap();
            for (int m = 0;m < x.length;m++) {
                int i = x[m];
                ImpExpTotalDataVO result = new ImpExpTotalDataVO();
                Date monthStartDate = DateUtils.stringToDate(finalYear + StringUtils.leftPadding(i + "",2,"0") +  "01","yyyyMMdd");
                Date monthEndDate = DateUtils.getMonthEnd(monthStartDate);
                if(flag && i > Integer.parseInt(currentMonth)) {
                    // 本月进口单量
                    result.setMonthImpSingleQuantity(0);
                    // 本月出口单量
                    result.setMonthExpSingleQuantity(0);
                    // 本月进口金额
                    result.setMonthImpAmountMoney(BigDecimal.ZERO);
                    // 本月出口金额
                    result.setMonthExpAmountMoney(BigDecimal.ZERO);
                    // 本月进口车次
                    result.setMonthImpTrainNumber(0);
                    // 本月出口车次
                    result.setMonthExpTrainNumber(0);
                } else {
                    // 本月进口单量
                    result.setMonthImpSingleQuantity(iImpOrderService.totalSingleQuantity(monthStartDate,monthEndDate));
                    // 本月出口单量
                    result.setMonthExpSingleQuantity(iExpOrderService.totalSingleQuantity(monthStartDate,monthEndDate));
                    // 本月进口金额
                    result.setMonthImpAmountMoney(iImpOrderService.totalAmountMoney(monthStartDate,monthEndDate));
                    // 本月出口金额
                    result.setMonthExpAmountMoney(iExpOrderService.totalAmountMoney(monthStartDate,monthEndDate));
                    // 本月进口车次
                    result.setMonthImpTrainNumber(crossBorderWaybillService.impTrainNumber(monthStartDate,monthEndDate));
                    // 本月出口车次
                    result.setMonthExpTrainNumber(crossBorderWaybillService.expTrainNumber(monthStartDate,monthEndDate));
                }
                handleMap.put(i + "",result);
            }
            return handleMap;
        };

        CountDownLatch countDownLatch = new CountDownLatch(threadMonthMap.size());
        threadMonthMap.forEach((idx,monthGroup)-> threadPoolTaskExecutor.execute(()->{
            try {
                queryF.apply(monthGroup).forEach(resultMap::put);
            } catch (Exception e) {
                log.error("处理月度业务量报表数据异常",e);
            } finally {
                countDownLatch.countDown();
            }
        }));
        try{
            countDownLatch.await();
        } catch (Exception e) {}
        return resultMap;
    }

    @Override
    public List<ImpExpAgencyFeeVO> monthImpExpAgencyFee(String year) {
        if(StringUtils.isNotEmpty(year) && (!StringUtils.isInteger(year) || year.length() != 4)) {
            throw new ServiceException("年份不正确");
        }
        List<ImpExpAgencyFeeVO> result = new ArrayList<>();
        year = TypeUtils.castToString(year,DateUtils.getCurrentDateYear());
        // 查询进口费用
        Map<String,BigDecimal> impCost = impReportService.monthAgencyFee(year);
        // 查询出口费用
        Map<String,BigDecimal> expCost = expReportService.monthAgencyFee(year);
        for(int i = 1;i <= 12;i++) {
            String key = String.format("%s-%s",year,StringUtils.autoFillZero(i,"00"));
            result.add(
                    new ImpExpAgencyFeeVO(key,TypeUtils.castToBigDecimal(impCost.get(key),BigDecimal.ZERO),TypeUtils.castToBigDecimal(expCost.get(key),BigDecimal.ZERO))
            );
        }
        return result;
    }
}
